home *** CD-ROM | disk | FTP | other *** search
- /*
- * WICONSETTER A companion utility to wIconify. wIconSetter allows
- * you to specify custom icons for windows ans screens
- * that normally use the default icons.
- *
- * wIconHandler.c The main Handler code.
- *
- * Copyright 1990 by Davide P. Cervone, all rights reserved.
- * You may use this code, provided this copyright notice is kept intact.
- */
-
- #include "wIconHandler.h"
-
- /*
- * Variables and routines needed for traps via SetFunction()
- */
-
- long OldOpenWindow;
- long OldSetWindowTitles;
- long OldOpenScreen;
- extern void cOpenWindow();
- extern void aOpenWindow();
- extern void cSetWindowTitles();
- extern void aSetWindowTitles();
- extern void cOpenScreen();
- extern void aOpenScreen();
-
- /*
- * Routines passed to the loader
- */
-
- extern void GetProgramName();
- extern int PrefixMatch();
- extern ICONWINDOW *FindIcon();
-
- extern WICONREF *wIconOf(); /* Part of wIconCalls.o */
-
-
- static ICONPROGRAM *FirstProgram; /* The list of icons */
- static ICONPROGRAM *ProgramAny; /* the special ANY program */
- static ICONDEFINE *FirstDefine; /* the list of defined icons */
-
- struct SysBase *SysBase;
-
- static char *IconProcess = ICONPROCNAME; /* Our process name */
- #define NOTICONIFY(p) (stricmp(p,IconProcess) != 0)
-
- #define TOUPPER(c) (((c)>='a'&&(c)<='z')?(c)-'a'+'A':c)
- #define MATCH(n1,n2) (stricmp(n1,n2))
- #define PREFIXMATCH(n1,n2) ((n1) == NAME_ANY || PrefixMatch(n1,n2) == 0)
- #define WPREFIXMATCH(n1,n2)\
- (((n1) == NAME_ANY && (n2) != SCREENICON) || PrefixMatch(n1,n2) == 0)
-
-
- /*
- * IconHandlerData is passed to the loader on startup.
- * It is used to pass values to the loader and receive initialized
- * values from the loader.
- */
-
- struct IconHandlerInfo IconHandlerData =
- {
- { /* the MsgPort is pre-setup */
- {NULL,NULL, NT_MSGPORT, 0, PORTNAME}, /* to include the name and */
- PA_IGNORE, 0, NULL, /* type so that it can just */
- {NULL,NULL,NULL, 0,0} /* be added to the port list */
- }, /* so it can be found later */
- MAJVERS,MINVERS, MINLOADVERS, /* version numbers */
- NULL, /* the loaded segment code */
-
- /*
- * The libraries needed by the handler
- */
-
- &IntuitionBase,
- &SysBase,
-
- /*
- * The routines and variables trapped by the loader
- */
-
- &aOpenWindow,
- &OldOpenWindow,
- &aSetWindowTitles,
- &OldSetWindowTitles,
- &aOpenScreen,
- &OldOpenScreen,
-
- /*
- * Data needed by the loader
- */
- &GetProgramName,
- &PrefixMatch,
- &FindIcon,
- &FirstDefine,
- &FirstProgram,
- &ProgramAny,
- };
-
-
- /*
- * Setup()
- *
- * This routine MUST be linked into the wIconSetter-Handler executable
- * as the first routine, so that the loader can find it.
- * It should check the version number for compatibility with the loader,
- * and should return NULL for an error, or the pointer to the shared
- * data structure if everything is OK.
- */
-
- struct IconHandlerInfo *Setup(version)
- int version;
- {
- if (version < MINLOADVERS) return(NULL);
- return(&IconHandlerData);
- }
-
-
- /*
- * PrefixMatch()
- *
- * Case-insensitive prefix match. NULL pointers and empty strings
- * only match themselves, and are not considered prefixes to any string.
- * The special SCREENICON value only matches itself.
- *
- * Return <0 if the first is smaller than the second,
- * =0 if the first is a prefix of the second,
- * >1 if the first is larger than the second.
- */
-
- int PrefixMatch(s1,s2)
- char *s1,*s2;
- {
- int match = -1;
-
- if (s1 == SCREENICON || s2 == SCREENICON) match = (s1 == s2)? 0: 1;
- else if (s1)
- {
- if (s2)
- {
- if (*s1)
- {
- while (TOUPPER(*s1) == TOUPPER(*s2) && *s2 != 0) s1++,s2++;
- if (*s1 == 0) match = 0; else match = *s1 - *s2;
- } else if (*s2 == 0) match = 0;
- } else match = 1;
- } else if (s2 == NULL) match = 0;
- return(match);
- }
-
-
-
- /*
- * FindIconWindow()
- *
- * Start with the first window of the given screen
- * While there are more windows to look at
- * If the window matches the name, return the window pointer
- * Otherwise go on to the next one
- * Return NULL if no match
- */
-
- static ICONWINDOW *FindIconWindow(IScreen,Name)
- ICONSCREEN *IScreen;
- char *Name;
- {
- ICONWINDOW *IWindow = IScreen->Window;
-
- while (IWindow)
- {
- if (WPREFIXMATCH(IWindow->Name,Name)) return(IWindow);
- IWindow = IWindow->Next;
- }
- return(NULL);
- }
-
-
- /*
- * FindIconScreen()
- *
- * While there are more screen to look at
- * If the screen matches the name, return the screen pointer
- * Otherwise go on to the next one
- * Return NULL if no match
- */
-
- static ICONSCREEN *FindIconScreen(IScreen,Name)
- ICONSCREEN *IScreen;
- char *Name;
- {
- while (IScreen)
- {
- if (PREFIXMATCH(IScreen->Name,Name)) return(IScreen);
- IScreen = IScreen->Next;
- }
- return(NULL);
- }
-
-
- /*
- * FindIconProgram()
- *
- * While there are more programs to look at
- * If the program name is ANY, always match, otherwise
- * compare the program against the given name
- * If there was a match, return the program
- * Otherwise move down to the next level of the tree
- * Return ProgramAny if nothing else matched
- */
-
- static ICONPROGRAM *FindIconProgram(IProgram,Name)
- ICONPROGRAM *IProgram;
- char *Name;
- {
- int result;
-
- while (IProgram)
- {
- if (IProgram->Name == NAME_ANY) result = 0;
- else result = MATCH(IProgram->Name,Name);
- if (result == 0) return(IProgram); else
- if (result < 0) IProgram = IProgram->Prev; else IProgram = IProgram->Next;
- }
- return(ProgramAny);
- }
-
-
-
- /*
- * FindIcon()
- *
- * Find the program structure for the given program name
- * If found,
- * Look through the program's list of screens
- * While there are more screens to check and we haven't found a window
- * Find the next matching screen
- * If found,
- * Look for the window on that screen and go on to the next screen
- * return the window (or NULL if none found)
- */
-
- ICONWINDOW *FindIcon(Program,theScreen,wTitle)
- char *Program;
- struct Screen *theScreen;
- char *wTitle;
- {
- ICONPROGRAM *IProgram;
- ICONSCREEN *IScreen;
- ICONWINDOW *IWindow = NULL;
-
- IProgram = FindIconProgram(FirstProgram,Program);
- if (IProgram)
- {
- IScreen = IProgram->Screen;
- while (IScreen && IWindow == NULL)
- {
- IScreen = FindIconScreen(IScreen,theScreen->DefaultTitle);
- if (IScreen)
- IWindow = FindIconWindow(IScreen,wTitle),
- IScreen = IScreen->Next;
- }
- }
- return(IWindow);
- }
-
-
- /*
- * StripPath()
- *
- * Start at the end of the string
- * While there are more characters to look at,
- * Get the preceding character
- * If it is '/' or ':' cancel the loop, otherwise back up a character
- * Clip the length of the name, if necessary
- * Terminate the Name string
- * Copy the name portion of the string into the Name buffer
- */
-
- static void StripPath(Name,s,len)
- char Name[MAXNAME];
- char *s;
- short len;
- {
- short i = 0;
- char c;
-
- s += len;
- while (len)
- {
- c = *(s-1);
- if (c == '/' || c == ':') len = 0;
- else len--, s--, i++;
- }
- if (i >= MAXNAME) i = MAXNAME-1;
- Name[i] = 0;
- while (i--) Name[i] = s[i];
- }
-
-
- /*
- * GetProgramName()
- *
- * If we have a task to look at,
- * If the task is a process
- * If the process has a task number and a CLI structure
- * Get the CLI structure, and use its current command name and length
- * If we haven't found the name yet,
- * Get the name from the task structure, and find its length
- * Strip the path portion off the name
- * Otherwise clear the name buffer
- */
-
- void GetProgramName(Name,theTask)
- char Name[MAXNAME];
- struct Process *theTask;
- {
- struct CommandLineInterface *theCLI;
- char *s = NULL;
- short len;
-
- if (theTask)
- {
- if (theTask->pr_Task.tc_Node.ln_Type == NT_PROCESS)
- {
- if (theTask->pr_TaskNum && theTask->pr_CLI)
- {
- theCLI = (struct CommandLineInterface *)BADDR(theTask->pr_CLI);
- if (theCLI->cli_CommandName)
- s = (char *)(BADDR(theCLI->cli_CommandName)), len = *s++;
- }
- }
- if (s == NULL)
- {
- s = theTask->pr_Task.tc_Node.ln_Name;
- len = strlen(s);
- }
- StripPath(Name,s,len);
- } else {
- Name[0] = 0;
- }
- }
-
-
- /*
- * HandleWindow()
- *
- * Get the name of the current process
- * If it is not the wIconify-Handler process
- * Look through the icon list for the given program/screen/window
- * If found
- * Get a copy of the icon (so we can modify it)
- * Remove the Autoiconify flag, if any (it is wIconSetter private)
- * Get the current icon position (if it exists)
- * Set the window to have the (modified) icon
- * If the original icon had the AUTOICONIFY flag and we are supposed
- * to do autoiconify, then iconify the window
- */
-
- static void HandleWindow(theWindow,DoAuto)
- struct Window *theWindow;
- int DoAuto;
- {
- char Program[MAXNAME];
- ICONWINDOW *theIcon;
- WICON tmpIcon;
-
- GetProgramName(Program,FindTask(NULL));
- if (NOTICONIFY(Program))
- {
- theIcon = FindIcon(Program,theWindow->WScreen,theWindow->Title);
- if (theIcon)
- {
- tmpIcon = theIcon->Icon;
- tmpIcon.Flags &= ~WI_AUTOICONIFY;
- wIconXY(wIconOf(theWindow),&(tmpIcon.x),&(tmpIcon.y));
- wSetIcon(theWindow,&tmpIcon);
- if ((theIcon->Icon.Flags & WI_AUTOICONIFY) && DoAuto)
- wIconify(theWindow);
- }
- }
- }
-
-
- /*
- * cOpenWindow()
- *
- * If the window openned successfully,
- * Check to see if it needs an icon.
- */
-
- void cOpenWindow(theWindow)
- struct Window *theWindow;
- {
- if (theWindow) HandleWindow(theWindow,TRUE);
- }
-
-
- /*
- * cSetWindowTitles()
- *
- * If a window is specified and it is getting a new title,
- * Check if the window with the new title should get an icon.
- */
-
- void cSetWindowTitles(theWindow,wTitle,sTitle)
- struct Window *theWindow;
- UBYTE *wTitle,*sTitle;
- {
- if (theWindow && wTitle != (UBYTE *)-ONE) HandleWindow(theWindow,FALSE);
- }
-
-
- /*
- * cOpenScreen()
- *
- * If the screen has a window (ie, wIconify added its backdrop window
- * to it already)
- * Get the name of the current task
- * If it is not the wIconify-Handler process itself
- * Look through the icon list for this program/screen
- * If it needs an icon
- * Get a copy of the screen icon for modification
- * Clear the AUTOICONIFY flag (it is wIconSetter private)
- * Set the screen to have the given icon
- * If the original icon has the AUTOICONIFY flag,
- * Iconify the screen
- */
-
- void cOpenScreen(theScreen)
- struct Screen *theScreen;
- {
- char Program[MAXNAME];
- ICONWINDOW *theIcon;
- WICON tmpIcon;
-
- if (theScreen && theScreen->FirstWindow)
- {
- GetProgramName(Program,FindTask(NULL));
- if (NOTICONIFY(Program))
- {
- theIcon = FindIcon(Program,theScreen,SCREENICON);
- if (theIcon)
- {
- tmpIcon = theIcon->Icon;
- tmpIcon.Flags &= ~WI_AUTOICONIFY;
- wSetScreenIcon(theScreen,&tmpIcon);
- if ((theIcon->Icon.Flags & WI_AUTOICONIFY))
- wIconifyScreen(theScreen);
- }
- }
- }
- }
-